﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// 用户第一次启动项目需要的操作 - 添加引用
// 参照 https://mp.weixin.qq.com/s/RqMlRFxBmKwngIJkdjMOZw 【2 - 添加对 ProjectPenguin.dll .. 的引用】
// 引用添加成功后以下using就不会报错。
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
using ProjectPenguin.Cards; // Y-GAMA的主框架类库
using NSGeo.Geometry; // 可选 图形数据描述依赖类库
using NSFramework; // 可选 GAMA结构模型类库
using NSFramework.NSModel;
using NSFramework.NSElement;
using NSFramework.NSSpecialElements;
using ProjectPenguin.Cards.ProcessorCardHelpers;

namespace UserDeck
{
    public class PolylineSplitCard : ProcessorCardBase
    {
        public PolylineSplitCard() : base("写死的框架", "框架", "简单框架", "JanyoDeck", "二开") { }
        static Guid _guid = Guid.Parse("{9C7F1004-DE2A-45CE-8C36-1CB85A9FE0EA}");
        public override Guid CardGuid => _guid;

        protected override void AddInputSideDataCards(IDataCardEmbedmentHelper helper)
        {
            helper.AddWellKnownTypeOfDataCard(typeof(int), "开间数量", "开间数量", "开间数量", ProjectPenguin.Cards.Enums.DataProcessingMode.OneByOne);
            helper.AddWellKnownTypeOfDataCard(typeof(int), "进深数量", "进深数量", "进深数量", ProjectPenguin.Cards.Enums.DataProcessingMode.OneByOne);
        }

        protected override void AddOutputSideDataCards(IDataCardEmbedmentHelper helper)
        {
            helper.AddWellKnownTypeOfDataCard(typeof(NSModel), "简单框架", "框架", "写死的框架", ProjectPenguin.Cards.Enums.DataProcessingMode.OneByOne);
        }

        public override void Build(IDataDelivery idd)
        {
            int kjNum = 0;
            int jsNum = 0;
            if (!idd.GetDataItem(0, ref kjNum)) return;
            if (!idd.GetDataItem(0, ref jsNum)) return;
            double kj = 5000;
            double js = 4000;
            Point3d Origin = new Point3d(0, 0, 3000);
            #region 轴网
            List<List<Point3d>> joints = new List<List<Point3d>>();  //节点
            for (int i = 0; i < jsNum + 1; i++)
            {
                Point3d start = Transform.Translation(i * js * Vector3d.YAxis) * Origin;
                List<Point3d> rawPts = new List<Point3d>();
                for (int j = 0; j < kjNum + 1; j++)
                {
                    rawPts.Add(Transform.Translation(j * kj * Vector3d.XAxis) * start);
                }
                joints.Add(rawPts);
            }
            List<List<Line>> XLines = new List<List<Line>>();  //x轴线
            for (int i = 0; i < jsNum + 1; i++)
            {
                Point3d start = Transform.Translation(i * js * Vector3d.YAxis) * Origin;
                List<Line> rawLines = new List<Line>();
                for (int j = 0; j < kjNum; j++)
                {
                    rawLines.Add(new Line(Transform.Translation(j * kj * Vector3d.XAxis) * start, Vector3d.XAxis * kj));
                }
                XLines.Add(rawLines);
            }
            List<List<Line>> YLines = new List<List<Line>>();  //y轴线
            for (int i = 0; i < kjNum + 1; i++)
            {
                Point3d start = Transform.Translation(i * kj * Vector3d.XAxis) * Origin;
                List<Line> rawLines = new List<Line>();
                for (int j = 0; j < jsNum; j++)
                {
                    rawLines.Add(new Line(Transform.Translation(j * js * Vector3d.YAxis) * start, Vector3d.YAxis * js));
                }
                YLines.Add(rawLines);
            }
            #endregion

            //框架模型
            NSModel frame = new NSModel();
            frame.BasePlane = new Plane(Point3d.Origin, Vector3d.ZAxis); //设置模型的基底平面
            frame.ZeroPlane = new Plane(Point3d.Origin, Vector3d.ZAxis); //设置模型的零平面

            #region 标准层
            NSStdFloor std1 = new NSStdFloor();
            std1.Height = 3000; //标准层层高
            std1.referencePlane = new Plane(new Point3d(0, 0, 3000), Vector3d.ZAxis); //设置标准层平面
            var planes = new List<Plane>();
            planes.Add(new Plane(new Point3d(0, 0, 6000), Vector3d.ZAxis));
            planes.Add(new Plane(new Point3d(0, 0, 9000), Vector3d.ZAxis));
            std1.relatedPlane = planes.ToArray(); //添加两层自然层
            //标准层参数
            NSStdFloorParam param = new NSStdFloorParam();
            param.BeamConcreteClass = ConcreteType.C30;  //混凝土等级
            param.ColumnConcreteClass = ConcreteType.C35;
            param.SlabConcreteClass = ConcreteType.C30;
            param.Dead = 2.5; //楼层所有楼板恒载
            param.Live = 2.5; //楼层所有楼板活载
            param.SlabThickness = 150; //楼层所有楼板厚度
            //将参数赋值给标准层  无效的设置：std1.Param.Dead = 2.5；
            std1.Param = param;
            #endregion

            #region 柱
            //柱截面 
            RectangleSection columnSection = new RectangleSection { Width = 400, Height = 450 };
            foreach (var list in joints)
            {
                foreach (var point in list)
                {
                    NSColumn column = new NSColumn();
                    column.Parent = std1; //设置构件所在标准层
                    column.Curve = new LineCurve(new Line(point, Vector3d.ZAxis * -3000)); //柱单元线
                    column.Section = columnSection; //设置截面
                    frame.AddElement(column); //模型中添加构件
                }
            }
            #endregion

            #region 梁
            //梁截面 矩形截面
            RectangleSection beamSection1 = new RectangleSection { Width = 300, Height = 600 };
            //梁墙荷载
            List<NSBWLoad> loads1 = new List<NSBWLoad>();
            loads1.Add(new DistributedLoad { Q = 10 }); //增加一个均布荷载
            //X向梁
            foreach (var list in XLines)
            {
                foreach (var line in list)
                {
                    NSBeam xbeam = new NSBeam();
                    xbeam.Parent = std1;
                    xbeam.Curve = new LineCurve(line);
                    xbeam.Section = beamSection1;
                    xbeam.Load = loads1;
                    frame.AddElement(xbeam);
                }
            }

            //梁截面 工字形
            ISection beamSection2 = new ISection
            {
                Height = 600,
                FlangeWidth1 = 250,
                FlangeWidth2 = 250,
                FlangeThickness1 = 30,
                FlangeThickness2 = 30,
                WebThickness = 50
            };
            //梁墙荷载
            List<NSBWLoad> loads2 = new List<NSBWLoad>();
            loads2.Add(new DistributeTorque { T = 5 }); //增加一个均布扭矩
            loads2.Add(new ConcentratedForce { P = 20, X = 2 }); //增加一个集中力
            //特殊梁定义
            NSSpecialBeamWrapper spBeam = new NSSpecialBeamWrapper();
            spBeam.AntiConstructSeismicDegree = AntiSeismicDegree.二级;
            spBeam.AntiSeismicDegree = AntiSeismicDegree.二级;
            spBeam.SteelMaterial = SteelType.Q345;
            for (int i = 0; i < YLines.Count(); i++)
            {
                foreach (var line in YLines[i])
                {
                    NSBeam ybeam = new NSBeam();
                    ybeam.Parent = std1;
                    ybeam.Curve = new LineCurve(line);
                    ybeam.Section = beamSection2;
                    ybeam.Load = loads2;
                    if (i == 0)
                    {
                        //修改第一列梁的抗震等级和钢材:
                        ybeam.SpecialBeam = spBeam;
                    }
                    frame.AddElement(ybeam);
                }
            }
            #endregion

            frame.ClassifyFloor(); //必须调用该函数，来生成按标高排序好的自然层
            frame.GenerateSlabs(); //生成楼板
            idd.SetDataItem(0, frame);
        }
    }
}
